// TODO.....

#include <iostream>
#include <string>
#include <sstream>
#include <cstdlib>
#include <unistd.h>
#include <readline/readline.h>
#include <readline/history.h>
#include "omd/omdtool.h"
#include "omd/param.h"

using std::string;
using std::istringstream;
using namespace omd;

string mpipath("mpirun");
string progpath("edrift"); // by default 'edrift' must be in path
string machfile;
string initload;
int numproc=1;

void help() {
  std::cout<<"\n"
  <<"                           E-DRIFT\n"
  <<"                     DIFFUSION SIMULATOR\n"
  <<"                         version 0.0\n\n"
  <<"  copyright (c) 2012, Yudi Rosandi, rosandi@physik.uni-kl.de\n"
  <<"                2013, Yudi Rosandi, rosandi@phys.unpad.ac.id\n\n";

  std::cout<<"command line options:\n"<<
  
  "    -np number-of-processor\n"
  "    -mach machine-file\n"
  "    -server /path/to/edrift-srv\n"
  "    -mpirun /path/to/mpirun\n\n";
  
  std::cout<<"command list:\n\n"<<
  
  "load filename\n"
  "    loads and run filename\n\n"
  "create filename [name]\n"
  "    create a domain from filename. if name is given use it\n";
  
  std::cout<<"TO DO...\n\n";
  
}

int main(int narg, char* varg[]) {

  ParamHandler param(narg,varg);
  
  if(param.exist("-h")||param.exist("-help")||param.exist("--help")) {
    help();
    return 0;
  }
  
  param.peek("-np",numproc);
  param.peek("-mach", machfile);
  param.peek("-machinefile", machfile);
  param.peek("-server",progpath);
  param.peek("-mpirun",mpipath);
  param.peek("-load",initload);
  
  std::cerr<<"\n"
           <<"                           E-DRIFT\n"
           <<"                     DIFFUSION SIMULATOR\n"
           <<"                         version 0.0\n\n"
           <<"  copyright (c) 2012, Yudi Rosandi, rosandi@physik.uni-kl.de\n\n";

  std::cerr<<"using "<<numproc<<" processors\n";
  
  // create pipe
  int pi[2];
  string cmdline;
  
  // check if serial version TODO
  // system((progpath+"> xxx-check-xxx").c_str);
  
  if(machfile=="") cmdline=mpipath;
  else cmdline=mpipath+" -machinefile "+machfile;
  cmdline.append(" -np "+as_string(numproc)+" ");
  cmdline.append(progpath);
  
  FILE* edrift=popen(cmdline.c_str(), "w");
  
  if(edrift==NULL) {
    std::cerr<<"failed running server\n";
    return 1;
  }
  
  if(initload!="") {
    string sld("load ");
    sld.append(initload);
    fprintf(edrift,"%s\n",sld.c_str());
    fflush(edrift);
    fprintf(edrift, "ping xxx-ping-xxx\n");
    fflush(edrift);
    while(!file_exist("xxx-ping-xxx")) usleep(100000);
    system("rm -f xxx-ping-xxx");
  }

  while(true) {
    string check;
    char* sline=readline("-> ");
    if(sline && *sline) add_history(sline);

    istringstream ss(sline);
    ss>>check; 
    
    if(check=="q"||check=="quit"||check=="exit") {
      fprintf(edrift, "exit\n");
      break; 
    } 
    
    else if(check=="loop") {
      string loopcmd(sline);
      loopcmd.append(";");
      while(loopcmd.find("end")==loopcmd.npos) {
        char *cc=readline("> ");
        loopcmd.append(cc);
        loopcmd.append(";");
        free(cc);
      }
      fprintf(edrift, "%s\n", loopcmd.c_str());
      fflush(edrift);
    } 
    
    else {
      fprintf(edrift, "%s\n", sline);
      fflush(edrift);
    }    
    
    fprintf(edrift, "ping xxx-ping-xxx\n");
    fflush(edrift);
    while(!file_exist("xxx-ping-xxx")) usleep(100000);
    system("rm -f xxx-ping-xxx");

    free(sline);
  }
  
  pclose(edrift);
  
  return 0;
}
